package ElectricCraft.frames;

import ElectricCraft.misc.GridBagPanel;
import ElectricCraft.model.ModelGroup;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * ModelSaveLoadFrame class implements save/load into package.
 */
public class ModelSaveLoadFrame extends JDialog {
    private final MainWindow parent;
    private final boolean isSave;
    public ModelSaveLoadFrame(MainWindow parent, boolean isSave) {
        super(parent.getFrame());

        // TODO: support creation of empty models (with specific inputs count)

        if (isSave) {
            setTitle("Save model");
        } else {
            setTitle("Open model");
        }

        this.parent = parent;

        this.isSave = isSave;

        setModal(true);
        setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

        initUI();

        setSize(400, 300);

        Rectangle bounds = parent.getFrame().getBounds();
        setLocation(
            bounds.x + (bounds.width - getWidth()) / 2,
            bounds.y + (bounds.height - getHeight()) / 2);

        setVisible(true);
    }

    private JEditorPane nameEdit;
    private PackageViewTree tree;
    private void initUI() {
        GridBagPanel panel = new GridBagPanel();

        tree = new PackageViewTree(parent, false);
        panel.setGridSize(2, 1);
        panel.addFill(0, 0, new JScrollPane(tree));

        if (isSave) {
            panel.setInsets(0, 5, 0, 5);
            panel.setWeights(0, 0);
            panel.addHorizontal(0, 1, new JLabel("Name:"));

            nameEdit = new JEditorPane();
            nameEdit.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
            panel.addHorizontal(1, 1, nameEdit);
        }

        GridBagPanel buttonBox = new GridBagPanel();

        buttonBox.addHorizontal(0, 0, Box.createHorizontalGlue());

        JButton saveBtn = new JButton(isSave ? "Save" : "Open");
        buttonBox.setWeights(0, 0);
        buttonBox.addHorizontal(1, 0, saveBtn);

        JButton cancelBtn = new JButton("Cancel");
        buttonBox.setWeights(0, 0);
        buttonBox.addHorizontal(2, 0, cancelBtn);

        panel.setGridSize(2, 1);
        panel.setInsets(5, 0, 5, 0);
        panel.addHorizontal(0, 2, buttonBox);

        add(panel);

        // create listeners
        tree.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() != MouseEvent.BUTTON1) {
                    return ;
                }

                if (isSave && e.getClickCount() == 1) {
                    PackageViewNode node = tree.getCurrentNode();
                    if (node != null && node.model != null) {
                        nameEdit.setText(node.model.name);
                    }
                }

                if (e.getClickCount() == 2) {
                    if (isSave) {
                        processSave();
                    } else {
                        processOpen();
                    }
                }
            }
        });

        saveBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (isSave) {
                    processSave();
                } else {
                    processOpen();
                }
            }
        });

        cancelBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                processCancel();
            }
        });

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                processCancel();
            }
        });
    }

    private ModelGroup resultGroup;
    private String resultName;
    private boolean canceled = false;

    public boolean wasCanceled() {
        return canceled;
    }

    public ModelGroup getResultGroup() {
        if (canceled) {
            throw new RuntimeException("Operation was canceled");
        }
        return resultGroup;
    }

    public String getResultName() {
        if (canceled) {
            throw new RuntimeException("Operation was canceled");
        }
        return resultName;
    }

    private void processSave() {
        resultName = nameEdit.getText();

        if (resultName.isEmpty()) {
            return ;
        }

        if (!isSave) {
            // make sure such name exists
            if (resultGroup == null || resultGroup.findModelByName(resultName) == null) {
                JOptionPane.showMessageDialog(
                    this,
                    "Model with such name does not exist",
                    resultName, JOptionPane.OK_OPTION);

                return ;
            }
        }

        dispose();
    }

    private void processOpen() {
        PackageViewNode node = tree.getCurrentNode();
        if (node == null || node.model == null) {
            return ;
        }

        resultName = node.model.name;
        resultGroup = node.group;

        dispose();
    }

    private void processCancel() {
        canceled = true;
        dispose();
    }
}
